/*
XPTracker - Alternative Agile Tracking Tool
Copyright (C) 2006-2009  Stephen Starkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package org.xptracker.search;

import org.xptracker.domain.*;
import org.apache.commons.logging.LogFactory;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Base class for {@link IndexingHelper} implementations which provides 
 * common behavior.
 * @author caliendo
 */
 public abstract class AbstractIndexingHelper implements IndexingHelper {

  /** The pattern to use for date parsing/formatting. */
  public static final String DATE_PATTERN = "yyyyMMdd";

  /**
   * Returns the String value for a {@link User} object.
   */
  private static String valueForUser(final User user) {
    if (user == null) {
      return "";
    }
    final StringBuilder builder = new StringBuilder(user.getUsername());
    builder.append(' ').append(user.getFullName());
    builder.append(' ').append(user.getEmail());
    return builder.toString();
  }

  /**
   * Determine the String value of the passed object which should 
   * be used by the indexer.
   * @param obj
   *    the object to determine the String value of
   * @return 
   *    the String value of the object
   */
  protected String stringValue(final Object obj) {
    final String value;

    if (obj == null) {
      value = "";
    } else if (obj instanceof String) {
      value = (String) obj;

    } else if (obj instanceof User) {
      value = valueForUser((User) obj);

    } else if (obj instanceof Date) {
      value = new SimpleDateFormat(DATE_PATTERN).format(obj);

    } else if (obj instanceof StoryCategory) {
      value = ((StoryCategory)obj).getName();

    } else if (obj instanceof Customer) {
      value = ((Customer)obj).getName();

    } else if (obj instanceof EffortEntry) {
      value = valueForUser(((EffortEntry)obj).getUser());

    } else if (obj instanceof Task) {
      final Task task = (Task) obj;
      final StringBuilder builder = new StringBuilder(task.getSummary()).append(' ');

      builder.append(task.getDescription()).append(' ');
      builder.append(valueForUser(task.getOwner()));

      value = builder.toString();

    } else if (obj instanceof BlogEntry) {
      final BlogEntry blogEntry = (BlogEntry) obj;
      final StringBuilder builder = new StringBuilder(blogEntry.getContent()).append(' ');

      builder.append(valueForUser(blogEntry.getCreator()));

      value = builder.toString();

    } else if (obj instanceof Iterable) {
      final StringBuilder builder = new StringBuilder();

      for (final Iterator iter = ((Iterable)obj).iterator(); iter.hasNext();) {
        builder.append(stringValue(iter.next()));

        if (iter.hasNext()) {
          builder.append(' ');
        }
      }

      value = builder.toString();
    } else if (obj instanceof WikiContent) {
      value = ((WikiContent)obj).getContent();
    } else {
      // just invoke toString on obj
      value = obj.toString();
    }

    // null should never be returned!
    if (value != null) {
      return value;
    }

    return "";
  }

  public String[] getQueryFields(Class clazz) {
    try {
        final List<String> queryFields = loadQueryFields(clazz);
        return queryFields.toArray(new String[queryFields.size()]);
    } catch (final Throwable t) {
      LogFactory.getLog(getClass()).error("Error determining query fields", t);
    }

    return new String[0];
  }
}
